/*
** Copyright (C) 2010 Calin Radoni
**
** This file is part of CHScanner.
**
** CHScanner is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** CHScanner is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with CHScanner. If not, see <http://www.gnu.org/licenses/>.
*/

#include "StdAfx.h"
#include ".\maddressip.h"

//---------------------------------------------------------------------------

MAddressIP::MAddressIP(void)
{
	Initialize();
}

MAddressIP::~MAddressIP(void)
{
}

//---------------------------------------------------------------------------

void MAddressIP::Set(DWORD val)
{
	ia.S_un.S_addr = val;
}

void MAddressIP::Set(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
{
	ia.S_un.S_un_b.s_b1 = b1;
	ia.S_un.S_un_b.s_b2 = b2;
	ia.S_un.S_un_b.s_b3 = b3;
	ia.S_un.S_un_b.s_b4 = b4;
}

void MAddressIP::Set(CString strIn)
{
	ia.S_un.S_addr = inet_addr(strIn);
}

//---------------------------------------------------------------------------

DWORD MAddressIP::GetD(void)
{
	return ia.S_un.S_addr;
}

bool MAddressIP::GetB(BYTE* b1, BYTE* b2, BYTE* b3, BYTE* b4)
{
	if(b1==NULL) return false;
	if(b2==NULL) return false;
	if(b3==NULL) return false;
	if(b4==NULL) return false;

	*b1 = ia.S_un.S_un_b.s_b1;
	*b2 = ia.S_un.S_un_b.s_b2;
	*b3 = ia.S_un.S_un_b.s_b3;
	*b4 = ia.S_un.S_un_b.s_b4;

	return true;
}

CString MAddressIP::GetS(void)
{
	CString str;

	str = inet_ntoa(ia);
	return str;
}

//---------------------------------------------------------------------------

void MAddressIP::Initialize(void)
{
	ia.S_un.S_addr = 0;
}

void MAddressIP::LoadFromPointer(MAddressIP* ipIn)
{
	if(ipIn==NULL){
		Initialize();
		return;
	}

	ia.S_un.S_addr = ipIn->GetD();
}

//---------------------------------------------------------------------------

bool MAddressIP::IsEmpty(void)
{
	return ia.S_un.S_addr==0 ? true : false;
}

//---------------------------------------------------------------------------

int MAddressIP::CompareWith(MAddressIP* ipIn)
{
	if(ipIn==NULL) return 1;

	if(ia.S_un.S_un_b.s_b1 < ipIn->ia.S_un.S_un_b.s_b1) return -1;
	if(ia.S_un.S_un_b.s_b1 > ipIn->ia.S_un.S_un_b.s_b1) return 1;

	if(ia.S_un.S_un_b.s_b2 < ipIn->ia.S_un.S_un_b.s_b2) return -1;
	if(ia.S_un.S_un_b.s_b2 > ipIn->ia.S_un.S_un_b.s_b2) return 1;

	if(ia.S_un.S_un_b.s_b3 < ipIn->ia.S_un.S_un_b.s_b3) return -1;
	if(ia.S_un.S_un_b.s_b3 > ipIn->ia.S_un.S_un_b.s_b3) return 1;

	if(ia.S_un.S_un_b.s_b4 < ipIn->ia.S_un.S_un_b.s_b4) return -1;
	if(ia.S_un.S_un_b.s_b4 > ipIn->ia.S_un.S_un_b.s_b4) return 1;

	return 0;
}

//---------------------------------------------------------------------------

DWORD MAddressIP::GetNetworkAddress(DWORD maskIn)
{
	DWORD res;

	res = ia.S_un.S_addr & maskIn;

	return res;
}

DWORD MAddressIP::GetBroadcastAddress(DWORD maskIn)
{
	DWORD res, mask;

	mask = ~maskIn;

	res = ia.S_un.S_addr | mask;

	return res;
}

CString MAddressIP::GetNetworkRange(DWORD maskIn)
{
	in_addr iMin, iMax;
	CString str;
	DWORD rev;

	iMin.S_un.S_addr = GetNetworkAddress(maskIn);
	rev = htonl(iMin.S_un.S_addr);
	rev++;
	iMin.S_un.S_addr = ntohl(rev);

	iMax.S_un.S_addr = GetBroadcastAddress(maskIn);
	rev = htonl(iMax.S_un.S_addr);
	rev--;
	iMax.S_un.S_addr = ntohl(rev);

	str  = inet_ntoa(iMin);
	str += _T("-");
	str += inet_ntoa(iMax);

	return str;
}

CString MAddressIP::GetNetworkRangeEx(DWORD maskIn)
{
	in_addr iMin, iMax;
	CString str, sss;
	BYTE bMin, bMax;
	DWORD rev;
	int i;

	iMin.S_un.S_addr = GetNetworkAddress(maskIn);
	rev = htonl(iMin.S_un.S_addr);
	rev++;
	iMin.S_un.S_addr = ntohl(rev);

	iMax.S_un.S_addr = GetBroadcastAddress(maskIn);
	rev = htonl(iMax.S_un.S_addr);
	rev--;
	iMax.S_un.S_addr = ntohl(rev);

	str.Empty();

	for(i=0; i<4; i++){
		switch(i){
			case 0 :
				bMin = iMin.S_un.S_un_b.s_b1;
				bMax = iMax.S_un.S_un_b.s_b1;
				break;
			case 1 :
				bMin = iMin.S_un.S_un_b.s_b2;
				bMax = iMax.S_un.S_un_b.s_b2;
				break;
			case 2 :
				bMin = iMin.S_un.S_un_b.s_b3;
				bMax = iMax.S_un.S_un_b.s_b3;
				break;
			case 3 :
				bMin = iMin.S_un.S_un_b.s_b4;
				bMax = iMax.S_un.S_un_b.s_b4;
				break;
		}
		if(bMin==bMax) sss.Format(_T("%d"), bMin);
		else           sss.Format(_T("%d-%d"), bMin, bMax);
		str += sss;

		if(i<3)
			str += _T(".");
	}

	return str;
}

//---------------------------------------------------------------------------
